package com.mashibing.webmaster.controller;

import com.alibaba.druid.util.StringUtils;
import com.mashibing.common.constant.WebMasterConstants;
import com.mashibing.common.enums.ExceptionEnums;
import com.mashibing.common.util.R;
import com.mashibing.common.vo.ResultVO;
import com.mashibing.webmaster.dto.UserDTO;
import com.mashibing.webmaster.entity.SmsUser;
import com.mashibing.webmaster.service.SmsMenuService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author SNA
 * @date 2025/10/23
 * @Description 认证、注册等基于用户的操作接口
 **/
@RestController
@RequestMapping("/sys")
@Slf4j
public class SmsUserController {

    @Autowired
    private SmsMenuService smsMenuService;


    /**
     * 用户登录接口
     * @param userDTO 用户登录信息DTO对象，包含用户名、密码、验证码和记住我标识
     * @param bindingResult 参数校验结果对象，用于获取参数校验错误信息
     * @return ResultVO 统一响应结果对象，登录成功返回成功状态，失败返回对应错误信息
     */
    @PostMapping("/login")
    public ResultVO login(@RequestBody @Valid UserDTO userDTO, BindingResult bindingResult) {

        //1、请求参数的非空校验
        if (bindingResult.hasErrors()) {
            // 参数不合法，响应对应的JSON信息
            log.info("【用户模块-登录】  参数不合法 userDTO = {}", userDTO);
            return R.error(ExceptionEnums.PARAMETER_ERROR);
        }

        //2、基于验证码 校验请求是否合理
        String realKaptcha = (String) SecurityUtils.getSubject().getSession().getAttribute(WebMasterConstants.KAPTCHA);
        if (!userDTO.getCaptcha().equalsIgnoreCase(realKaptcha)) {
            log.info("【用户模块-登录】  验证码错误, kaptcha = {}, realKaptcha = {}", userDTO.getCaptcha(), realKaptcha);
            return R.error(ExceptionEnums.CAPTCHA_ERROR);
        }

        //3、基于用户名和密码做Shiro的认证操作
        UsernamePasswordToken token = new UsernamePasswordToken(userDTO.getUsername(), userDTO.getPassword());
        token.setRememberMe(userDTO.getRememberMe());
        try {
            SecurityUtils.getSubject().login(token);
        } catch (AuthenticationException e) {
            //4、根据Shiro的认证，返回响应信息
            log.info("【用户模块-登录】 认证失败。用户名或密码错误，ex = {}", e.getMessage());
            return R.error(ExceptionEnums.AUTHEN_ERROR);
        }

        // 到这，代表认证成功
        return R.ok();
    }


    /**
     * 获取当前登录用户信息
     *
     * @return ResultVO 包含用户信息的统一响应结果，包含昵称等用户基本信息
     */
    @GetMapping("/user/info")
    public ResultVO info() {
        //1、基于SecurityUtils获取当前登录用户信息
        Subject subject = SecurityUtils.getSubject();   // 获取当前安全上下文中的用户主体对象
        SmsUser smsUser = (SmsUser) subject.getPrincipal();   // 从主体对象中提取用户的身份凭证信息

        if (smsUser == null) {
            log.info("【用户模块-获取用户信息】  用户未登录！！");
            return R.error(ExceptionEnums.NOT_LOGIN);
        }

        //2、封装结果返回
        Map<String, Object> data = new HashMap<>();
        data.put("nickname", smsUser.getNickname());
        data.put("username", smsUser.getUsername());

        return R.ok(data);
    }


    @GetMapping("/menu/user")
    public ResultVO menuUser() {

        //1、基于SecurityUtils获取当前登录用户信息
        SmsUser smsUser = (SmsUser) SecurityUtils.getSubject().getPrincipal();

        if (smsUser == null) {
            log.info("【用户模块-获取用户菜单信息】  用户未登录！！");
            return R.error(ExceptionEnums.NOT_LOGIN);
        }

        List<Map<String, Object>> data = smsMenuService.findUserMenu(smsUser.getId());

        if (data == null) {
            log.error("【用户模块-获取用户菜单信息】  用户菜单为空！！id = {}", smsUser.getId());
            return R.error(ExceptionEnums.USER_MENU_ERROR);

        }

        //3、返回结果
        return R.ok(data);
    }
}
